Skip to content

Conversation

@svs-quic
Copy link
Contributor

This extension adds 6 instructions that can do multi-word load/store.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest

This patch adds assembler only support.

This extension adds 6 instructions that can do multi-word load/store.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest

This patch adds assembler only support.
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' llvm:mc Machine (object) code labels Dec 13, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 13, 2024

@llvm/pr-subscribers-mc
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-backend-risc-v

Author: Sudharsan Veeravalli (svs-quic)

Changes

This extension adds 6 instructions that can do multi-word load/store.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest

This patch adds assembler only support.


Full diff: https://github.com/llvm/llvm-project/pull/119823.diff

14 Files Affected:

  • (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/docs/ReleaseNotes.md (+2)
  • (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+12)
  • (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2)
  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+58)
  • (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+1-1)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2)
  • (added) llvm/test/MC/RISCV/xqcilsm-aliases-valid.s (+35)
  • (added) llvm/test/MC/RISCV/xqcilsm-invalid.s (+112)
  • (added) llvm/test/MC/RISCV/xqcilsm-valid.s (+35)
  • (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index c268f75a0fd8df..715d9e414e6114 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -191,6 +191,7 @@
 // CHECK-NEXT:     xqcia                0.2       'Xqcia' (Qualcomm uC Arithmetic Extension)
 // CHECK-NEXT:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select Extension)
 // CHECK-NEXT:     xqcicsr              0.2       'Xqcicsr' (Qualcomm uC CSR Extension)
+// CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2867dcceb84fd7..f6a0dd4bf2383c 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -435,6 +435,9 @@ The current vendor extensions supported are:
 ``experimental-Xqcicsr``
   LLVM implements `version 0.2 of the Qualcomm uC CSR extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
 
+``experimental-Xqcilsm``
+  LLVM implements `version 0.2 of the Qualcomm uC Load Store Multiple extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
+
 ``experimental-Xqcisls``
   LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm.  All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index ddee4ab8ce1b37..5d2ff17ee19848 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -223,6 +223,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load Store Multiple)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 7c91dc07bbd3e5..5b9946e5132e40 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -724,6 +724,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
   bool isUImm48() const { return IsUImm<48>(); }
   bool isUImm64() const { return IsUImm<64>(); }
 
+  bool isUImm5NonZero() const {
+    if (!isImm())
+      return false;
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm8GE32() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -1506,6 +1516,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
   case Match_InvalidUImm5:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+  case Match_InvalidUImm5NonZero:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
   case Match_InvalidUImm6:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
   case Match_InvalidUImm7:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b8ca32434aa43e..99017195185fd3 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -690,6 +690,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
                         "Qualcomm uC Arithmetic custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
                         "Qualcomm uC Conditional Select custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32,
+                        "Qualcomm uC Load Store Multiple custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 9e36d62352ae51..8b407a9fd25505 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -301,6 +301,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM3,
   OPERAND_UIMM4,
   OPERAND_UIMM5,
+  OPERAND_UIMM5_NONZERO,
   OPERAND_UIMM5_LSB0,
   OPERAND_UIMM6,
   OPERAND_UIMM6_LSB0,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index d1922eb0262792..ebaf2a28ba881c 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1375,6 +1375,14 @@ def HasVendorXqcics
       AssemblerPredicate<(all_of FeatureVendorXqcics),
                          "'Xqcics' (Qualcomm uC Conditional Select Extension)">;
 
+def FeatureVendorXqcilsm
+    : RISCVExperimentalExtension<"xqcilsm", 0, 2,
+                                 "'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
+def HasVendorXqcilsm
+    : Predicate<"Subtarget->hasVendorXqcilsm()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcilsm),
+                         "'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 3af49d7e74460c..9a61b38cfce2d8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,13 @@
 // Operand and SDNode transformation definitions.
 //===----------------------------------------------------------------------===//
 
+def uimm5nonzero : RISCVOp<XLenVT>,
+                   ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
+  let DecoderMethod = "decodeUImmNonZeroOperand<5>";
+  let OperandType = "OPERAND_UIMM5_NONZERO";
+}
+
 def uimm11 : RISCVUImmLeafOp<11>;
 
 //===----------------------------------------------------------------------===//
@@ -105,6 +112,26 @@ class QCISELECTICCI<bits<3> funct3, string opcodestr>
   let rs1 = imm;
 }
 
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class QCILoadMultiple<bits<2> func2, DAGOperand InTyRs2, string opcodestr>
+    : RVInstRBase<0b111, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+                  (ins GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
+                  opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
+  bits<7> imm;
+  let Inst{31-25} = {func2, imm{6-2}};
+}
+
+
+// rd corresponds to the source for the store 'rs3' described in the spec.
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class QCIStoreMultiple<bits<2> func2, DAGOperand InTyRs2, string opcodestr>
+    : RVInstRBase<0b111, OPC_CUSTOM_1, (outs),
+                  (ins GPR:$rd, GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
+                  opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
+  bits<7> imm;
+  let Inst{31-25} = {func2, imm{6-2}};
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -167,3 +194,34 @@ let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
   def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
   def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
 } // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
+
+let Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm" in {
+    def QC_SWM : QCIStoreMultiple<0b00, GPRNoX0, "qc.swm">;
+    def QC_SWMI : QCIStoreMultiple<0b01, uimm5nonzero, "qc.swmi">;
+    def QC_SETWM : QCIStoreMultiple<0b10, GPRNoX0, "qc.setwm">;
+    def QC_SETWMI : QCIStoreMultiple<0b11, uimm5nonzero, "qc.setwmi">;
+
+    def QC_LWM : QCILoadMultiple<0b00, GPRNoX0, "qc.lwm">;
+    def QC_LWMI : QCILoadMultiple<0b01, uimm5nonzero, "qc.lwmi">;
+} // Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm"
+
+//===----------------------------------------------------------------------===//
+// Aliases
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXqcilsm, IsRV32] in {
+let EmitPriority = 0 in {
+  def : InstAlias<"qc.swm $rs3, $rs2, (${rs1})",
+                  (QC_SWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+  def : InstAlias<"qc.swmi $rs3, $length, (${rs1})",
+                  (QC_SWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
+  def : InstAlias<"qc.setwm $rs3, $rs2, (${rs1})",
+                  (QC_SETWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+  def : InstAlias<"qc.setwmi $rs3, $length, (${rs1})",
+                  (QC_SETWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
+  def : InstAlias<"qc.lwm $rd, $rs2, (${rs1})",
+                  (QC_LWM GPRNoX0:$rd, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+  def : InstAlias<"qc.lwmi $rd, $length, (${rs1})",
+                  (QC_LWMI GPRNoX0:$rd, GPR:$rs1, uimm5nonzero:$length, 0)>;
+} // EmitPriority = 0
+} // Predicates = [HasVendorXqcilsm, IsRV32]
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index de3d5564210ff4..cafc9d304e83a7 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcisls"}};
+      {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
 
   if (HasI && HasE)
     return getIncompatibleError("i", "e");
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index cdccc712a46981..f63bc944ccf22e 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -84,6 +84,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
@@ -392,6 +393,7 @@
 ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
 ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
diff --git a/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s b/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s
new file mode 100644
index 00000000000000..e9aec14c3c3aa0
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s
@@ -0,0 +1,35 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.swm   t0, s4, 0(gp)
+# CHECK-ENC: encoding: [0xab,0xf2,0x41,0x01]
+qc.swm x5, x20, (x3)
+
+# CHECK-INST: qc.swmi  a0, 4, 0(tp)
+# CHECK-ENC: encoding: [0x2b,0x75,0x42,0x40]
+qc.swmi x10, 4, (x4)
+
+# CHECK-INST: qc.setwm tp, t5, 0(sp)
+# CHECK-ENC: encoding: [0x2b,0x72,0xe1,0x81]
+qc.setwm x4, x30, (x2)
+
+# CHECK-INST: qc.setwmi    t0, 31, 0(a2)
+# CHECK-ENC: encoding: [0xab,0x72,0xf6,0xc1]
+qc.setwmi x5, 31, (x12)
+
+# CHECK-INST: qc.lwm   t2, ra, 0(s4)
+# CHECK-ENC: encoding: [0x8b,0x73,0x1a,0x00]
+qc.lwm x7, x1, (x20)
+
+# CHECK-INST: qc.lwmi  a3, 9, 0(s7)
+# CHECK-ENC: encoding: [0x8b,0xf6,0x9b,0x40]
+qc.lwmi x13, 9, (x23)
diff --git a/llvm/test/MC/RISCV/xqcilsm-invalid.s b/llvm/test/MC/RISCV/xqcilsm-invalid.s
new file mode 100644
index 00000000000000..c59260b5718d0b
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-invalid.s
@@ -0,0 +1,112 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcilsm < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcilsm < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: expected register
+qc.swm x5, x20, 12(20)
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.swm x5, x0, 12(x3)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.swm x5, x3
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.swm x5, x20, 45(x3)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.swm x5, x20, 12(x3)
+
+
+# CHECK: :[[@LINE+1]]:20: error: expected register
+qc.swmi x10, 4, 20(4)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.swmi x10, 4, 20
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.swmi x10, 32, 20(x4)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.swmi x10, 0, 20(x4)
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.swmi x10, 4, 45(x4)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.swmi x10, 4, 20(x4)
+
+
+# CHECK: :[[@LINE+1]]:23: error: expected register
+qc.setwm x4, x30, 124(2)
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.setwm x4, x0, 124(x2)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setwm x4, x30, 124
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.setwm x4, x30, 128(x2)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.setwm x4, x30, 124(x2)
+
+
+# CHECK: :[[@LINE+1]]:22: error: expected register
+qc.setwmi x5, 31, 12(12)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setwmi x5, 31, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the range [1, 31]
+qc.setwmi x5, 37, 12(x12)
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the range [1, 31]
+qc.setwmi x5, 0, 12(x12)
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.setwmi x5, 31, 98(x12)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.setwmi x5, 31, 12(x12)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.lwm x7, x1, 24(20)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lwm x7, x1, 24
+
+# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.lwm x0, x1, 24(x20)
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.lwm x7, x1, 46(x20)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.lwm x7, x1, 24(x20)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.lwmi x13, 9, 4(23)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lwmi x13, 9, 4
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.lwmi x0, 9, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.lwmi x13, 44, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [1, 31]
+qc.lwmi x13, 0, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes in the range [0, 124]
+qc.lwmi x13, 9, 77(x23)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.lwmi x13, 9, 4(x23)
diff --git a/llvm/test/MC/RISCV/xqcilsm-valid.s b/llvm/test/MC/RISCV/xqcilsm-valid.s
new file mode 100644
index 00000000000000..4893e074df327c
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-valid.s
@@ -0,0 +1,35 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.swm   t0, s4, 12(gp)
+# CHECK-ENC: encoding: [0xab,0xf2,0x41,0x07]
+qc.swm x5, x20, 12(x3)
+
+# CHECK-INST: qc.swmi  a0, 4, 20(tp)
+# CHECK-ENC: encoding: [0x2b,0x75,0x42,0x4a]
+qc.swmi x10, 4, 20(x4)
+
+# CHECK-INST: qc.setwm tp, t5, 124(sp)
+# CHECK-ENC: encoding: [0x2b,0x72,0xe1,0xbf]
+qc.setwm x4, x30, 124(x2)
+
+# CHECK-INST: qc.setwmi    t0, 31, 12(a2)
+# CHECK-ENC: encoding: [0xab,0x72,0xf6,0xc7]
+qc.setwmi x5, 31, 12(x12)
+
+# CHECK-INST: qc.lwm   t2, ra, 24(s4)
+# CHECK-ENC: encoding: [0x8b,0x73,0x1a,0x0c]
+qc.lwm x7, x1, 24(x20)
+
+# CHECK-INST: qc.lwmi  a3, 9, 4(s7)
+# CHECK-ENC: encoding: [0x8b,0xf6,0x9b,0x42]
+qc.lwmi x13, 9, 4(x23)
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index cf06ec5670346e..bef3f571b174d3 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1117,6 +1117,7 @@ Experimental extensions
     xqcia                0.2
     xqcics               0.2
     xqcicsr              0.2
+    xqcilsm              0.2
     xqcisls              0.2
 
 Supported Profiles

Copy link
Member

@lenary lenary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but please wait for Craig to approve as well.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@svs-quic svs-quic merged commit 668d968 into llvm:main Dec 13, 2024
9 checks passed
@svs-quic svs-quic deleted the Xqcilsm branch December 13, 2024 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:RISC-V clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category llvm:mc Machine (object) code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants